import dayjs from 'dayjs'
import { HTML_THEME_KEY } from './constants'
import { VxeUI } from 'vxe-table'
import { useHtmlThemeStore } from '@/pages/index/stores/theme'
import CryptoJS from 'crypto-js'

const DEFAULT_KEY = '1234567890abcdef' // 必须是16字节长度（对于AES-128）

/**
 * 加密函数（随机生成IV并将其拼接在加密内容前）
 * @param content 要加密的内容
 * @param key 加密密钥
 * @returns Base64编码后的密文（包含IV）
 */
export function AesEncrypt(content: string, key: string = DEFAULT_KEY): string {
  // 生成16字节IV
  let iv = CryptoJS.lib.WordArray.random(16)

  // const iv_ = new Uint8Array(16)
  // iv_.set([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
  // iv = CryptoJS.lib.WordArray.create(iv_)
  const keyHex = CryptoJS.enc.Utf8.parse(key)

  // 执行加密
  const encrypted = CryptoJS.AES.encrypt(content, keyHex, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })

  // 将IV和加密后的内容合并成一个Base64字符串
  const combined = iv.concat(encrypted.ciphertext).toString(CryptoJS.enc.Base64)
  return combined
}

/**
 * 解密函数（从密文中提取IV进行解密）
 * @param ciphertext Base64编码的密文（包含IV）
 * @param key 解密密钥
 * @returns 解密后的内容
 */
export function AesDecrypt(ciphertext: string, key: string = DEFAULT_KEY): string {
  const keyHex = CryptoJS.enc.Utf8.parse(key)
  // 解析Base64字符串，提取IV和加密内容
  const parsed = CryptoJS.enc.Base64.parse(ciphertext)
  // 前4个word为IV（每个word是4字节，总共16字节）
  const iv = CryptoJS.lib.WordArray.create(parsed.words.slice(0, 4))
  const encryptedContent = CryptoJS.lib.WordArray.create(parsed.words.slice(4))
  // 构造 CipherParams 对象
  const cipherParams = CryptoJS.lib.CipherParams.create({
    ciphertext: encryptedContent
  })
  const decrypted = CryptoJS.AES.decrypt(cipherParams, keyHex, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 })
  return decrypted.toString(CryptoJS.enc.Utf8)
}


/**
 * 改变html主题
 * @param light
 */
export function ChangeHtmlTheme(light = true) {
  const stores = useHtmlThemeStore()
  stores.setThemeLight(light)
  localStorage.setItem(HTML_THEME_KEY, String(light))
  if (light === true) {
    document.documentElement.classList.remove('dark')
    document.documentElement.classList.remove('black-theme')
    // 切换为默认主题
    VxeUI.setTheme('light')
  } else {
    document.documentElement.classList.add('dark')
    document.documentElement.classList.add('black-theme')
    // 切换为暗黑主题
    VxeUI.setTheme('dark')
  }
}

/**
 * 初始化html主题
 */
export function InitHTMLTheme() {
  const stores = useHtmlThemeStore()
  const listeners = {
    dark: (mediaQueryList: { matches: any }) => {
      if (mediaQueryList.matches) {
        console.debug('您切换到深色模式了！')
        ChangeHtmlTheme(false)
      }
    },
    light: (mediaQueryList: { matches: any }) => {
      if (mediaQueryList.matches) {
        console.debug('您切换到浅色模式了！')
        ChangeHtmlTheme()
      }
    }
  }

  window.matchMedia('(prefers-color-scheme: dark)').onchange = listeners.dark
  window.matchMedia('(prefers-color-scheme: light)').onchange = listeners.light

  const light = localStorage.getItem(HTML_THEME_KEY) ?? 'true'
  if (light === 'true') {
    document.documentElement.classList.remove('dark')
    document.documentElement.classList.remove('black-theme')
    stores.setThemeLight(true)
    VxeUI.setTheme('light')
  } else {
    document.documentElement.classList.add('dark')
    document.documentElement.classList.add('black-theme')
    stores.setThemeLight(false)
    VxeUI.setTheme('dark')
  }
}

/**
 * 通过转成json再解析的方式 创建一个新的对象,
 * @警告 由于结果中的对象都是新的,所以不要企图用这个对象操作原来的对象
 * @param original 原来的对象
 * @returns
 */
export function copyObject<T>(original: T): T {
  return JSON.parse(JSON.stringify(original))
}
/**
 * 将日期转成字符串
 * @param date 日期
 * @returns
 */
export function dateToString(date: Date): string {
  return dayjs(date).format('YYYY-MM-DD HH:mm:ss')
}
/**
 * 将字符串转成js中的Date
 * @param str 字符串
 * @returns
 */
export function stringToDate(str: string): Date {
  return new Date(str)
}
/**
 * 请求图片转成 blob
 * @param imgUrl
 * @returns
 */
export function requestPictureToBlob(imgUrl: string): Promise<Blob> {
  return new Promise((resolve, reject) => {
    fetch(imgUrl)
      .then((response) => {
        resolve(response.blob())
      })
      .catch((err) => {
        reject(err)
      })
  })
}

/**
 * 请求图片转成base64
 * @param url
 * @returns
 */
export function requestPictureToBase64(imgUrl: string): Promise<string> {
  return new Promise((resolve, reject) => {
    fetch(imgUrl)
      .then((response) => {
        return response.blob()
      })
      .then((blob) => {
        const oFileReader = new FileReader()
        oFileReader.onloadend = function (e) {
          // base64结果
          const base64 = e.target!.result as string
          // console.log(base64);
          resolve(base64)
        }
        oFileReader.readAsDataURL(blob)
      })
      .catch((err) => {
        reject(err)
      })
  })
}
/**
 * 将图片转成blob
 * @param file 
 * @returns 
 */

export function fileToBlob(file: File): Promise<Blob> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => {
      const blob = new Blob([reader.result!], { type: file.type })
      resolve(blob)
    }
    reader.onerror = reject
    reader.readAsArrayBuffer(file)
  })
}

/***
 *
 * 获取请求的UUID，指定长度和进制,如
 * getUUID(8, 2)   //"01001010" 8 character (base=2)
 * getUUID(8, 10) // "47473046" 8 character ID (base=10)
 * getUUID(8, 16) // "098F4D35"。 8 character ID (base=16)
 *
 */
export function getUUID(len?: number, radix?: number) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  const uuid = []
  radix = radix || chars.length
  if (len) {
    for (let i = 0; i < len; i++) {
      uuid[i] = chars[0 | (Math.random() * radix)]
    }
  } else {
    let r = 0
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'
    for (let i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}
